/*
 *
 *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  SPDX-License-Identifier: Apache-2.0
 *
 */
import React, {useCallback, useContext, useEffect, useState} from 'react';
import {
    Button,
    Card,
    Justify,
    Layout,
    Modal,
    PagingQuery,
    SearchBox,
    Table,
    TableColumn,
    Form,
    Select, Input, RadioGroup, Radio,
} from 'tea-component';
import {Link, useHistory, useRouteMatch} from 'react-router-dom';
import {ChainNodeTypeDescMap, IChainNodeItem} from 'src/common/apis/chains/interface';
import {PAGE_SIZE_OPTIONS, splitUrl} from 'src/utils/common';
import {
    getGroupList,
    getNodeList,
    useFetchChainNodeList, useFetchCreateOrgNode,
    useFetchRemoveNode
} from 'src/common/apis/chains/hooks';
import {ChainDetailContext} from '../chain-detail';
import GlossaryGuide from '../../../common/components/glossary-guide';
import {Controller, useForm, useWatch} from "react-hook-form";
import formUtils, {Validator} from "../../../utils/form-utils";

const { TextArea } = Input;

const {Content} = Layout;
const {pageable, autotip} = Table.addons;

export function ChainNode() {
    const {url} = useRouteMatch();
    const {chainId} = useContext(ChainDetailContext);
    const {list, totalCount, fetch} = useFetchChainNodeList();
    const [pageQuery, setPageQuery] = useState<Required<PagingQuery>>({pageSize: 10, pageIndex: 1});
    const [searchValue, setSearchValue] = useState<string>('');
    const [searchValueInput, setSearchValueInput] = useState<string>('');
    const chainMode = splitUrl(location.search).get('chainMode');
    const {fetchRemoveNode} = useFetchRemoveNode();
    const {fetchCreateOrgNode} = useFetchCreateOrgNode();
    const go = useHistory();

    let defaultColumn: TableColumn<IChainNodeItem>[] = [
        {
            key: 'NodeName',
            header: '节点名称',
        },
    ];
    if (chainMode !== 'public') {
        defaultColumn.push({
            key: 'OrgName',
            header: '所属组织',
        });
    }
    defaultColumn = defaultColumn.concat([
        {
            key: 'NodeType',
            header: '节点类型',
            render: (record) => ChainNodeTypeDescMap[record.NodeType],
        },
        {
            key: 'NodeId',
            header: <GlossaryGuide title={'节点ID'}/>,
        },
        {
            key: 'NodeAddr',
            header: <GlossaryGuide title={'节点地址'}/>,
            // eslint-disable-next-line react/display-name
            render: ({NodeAddr, NodePort}: IChainNodeItem) => (
                <>
                    {NodeAddr}:{NodePort}
                </>
            ),
        },
        {
            key: 'UpdateType',
            header: <GlossaryGuide title={'账本同步类型'}/>,
        },
        {
            key: 'Action',
            header: '操作',
            // eslint-disable-next-line react/display-name
            render: (record: any) => {
                const {Id, OrgNodeId, NodeId,NodeType} = record;
                // return <Link to={`${url}/details/${Id}?chainMode=${chainMode}&OrgNodeId=${OrgNodeId}`}>查看</Link>;
                return <>
                    <Button
                        type={'link'}
                        onClick={() => {
                            go.push(`${url}/details/${Id}?chainMode=${chainMode}&OrgNodeId=${OrgNodeId}`);
                        }}
                    >
                        查看
                    </Button>
                    <Button
                        type="link"
                        onClick={() => {
                            fetchDeleteCert({ChainId: chainId, NodeId,NodeType, NodeOrgId: record.OrgId, Type: 1});
                        }}
                    >
                        删除
                    </Button>
                </>
            },
        },
    ]);

    const fetchList = useCallback(() => {
        if (!chainId) return;
        fetch({
            ChainId: chainId,
            PageNum: pageQuery.pageIndex - 1,
            PageSize: pageQuery.pageSize,
            NodeName: searchValue ?? '',
        });
    }, [chainId, pageQuery, searchValue, fetch]);

    const fetchDeleteCert = useCallback(
        (param) => {
            fetchRemoveNode(param).then(() => {
                fetchList();
            });
        },
        [fetchList],
    );
    const fetchAddOrgNode = useCallback(
        (param) => {
            fetchCreateOrgNode(param).then(() => {
                fetchList();
            });
        },
        [fetchList],
    );

    useEffect(() => {
        fetchList();
    }, [fetchList]);

    const [nodeVisible, setNodeVisible] = useState(false);

    const handleInstallClick = useCallback(() => {
        setNodeVisible(true);
    }, []);

    return (
        <>
            <Layout>
                <Content>
                    <Content.Header title="区块链管理/节点信息"/>
                    <Content.Body full>
                        <Justify
                            left={
                                <Button type={'primary'} onClick={handleInstallClick}>
                                    新增节点
                                </Button>
                            }
                            right={
                                <SearchBox
                                    placeholder="请输入节点名搜索"
                                    size="l"
                                    value={searchValueInput}
                                    onChange={(value) => setSearchValueInput(value)}
                                    onSearch={(value) => setSearchValue(value ?? '')}
                                    onClear={() => setSearchValue('')}
                                />
                            }
                        />
                        <Card className="tea-mt-5n">
                            <Table
                                recordKey="Id"
                                records={list}
                                columns={defaultColumn}
                                addons={[
                                    pageable({
                                        recordCount: totalCount,
                                        pageIndex: pageQuery.pageIndex,
                                        pageSize: pageQuery.pageSize,
                                        pageSizeOptions: PAGE_SIZE_OPTIONS,
                                        onPagingChange: ({pageIndex, pageSize}) =>
                                            setPageQuery({pageIndex: pageIndex ?? 1, pageSize: pageSize ?? 10}),
                                    }),
                                    autotip({
                                        emptyText: '暂无数据',
                                        isFound: !!searchValue.length,
                                        onClear: () => {
                                            setSearchValue('');
                                            setSearchValueInput('');
                                        },
                                    }),
                                ]}
                            />
                        </Card>
                        <NodeModal
                            visible={nodeVisible}
                            close={() => setNodeVisible(false)}
                            onSubmit={(params: any) => {
                                fetchAddOrgNode(params)
                                setNodeVisible(false);
                            }}
                        />
                    </Content.Body>
                </Content>
            </Layout>
        </>
    );
}

function NodeModal({visible, close, onSubmit}: any) {
    const {chainId} = useContext(ChainDetailContext);

    const [orgList, setOrgList] = useState<any>([]);
    const [nodeList, setNodeList] = useState<any>([]);


    const {
        control,
        reset,
        formState: {isValidating, isSubmitted, isValid},
        getValues,
        setValue,
        trigger,
    } = useForm({
        defaultValues: {
            ChainId: chainId,
            OrgId: '',
            NodeId: '',
            Host: '',
            RpcPort: '',
            P2pPort: '',
            NodeType: '0',
            Reason:''
        },
        mode: 'onBlur',
    });

    // 监听 OrgId 的变化
    const orgId = useWatch({control, name: 'OrgId'});

    useEffect(() => {
        if (visible) {
            getGroupList({ChainId: chainId})
                .then(res => setOrgList(res))
                .catch(error => console.error('获取组织列表失败:', error));
        }
    }, [visible, chainId]);

    useEffect(() => {
        const orgId = getValues('OrgId');
        if (visible && orgId) {
            getNodeList({ChainId: chainId, OrgId: orgId})
                .then(res => {
                    setNodeList(res)
                    setValue('NodeId', '');
                })
                .catch(error => console.error('获取节点列表失败:', error));
        } else {
            setNodeList([]);
            setValue('NodeId', '');
        }
    }, [visible, orgId, chainId]);


    const onClose = () => {
        close();
        reset({});
    };

    const handleSubmit = () => {
        onSubmit({...getValues(), Type: 0, RpcPort: +getValues().RpcPort, P2pPort: +getValues().P2pPort,NodeType:+getValues().NodeType})
        reset({});
    };

    const groups = {
        0: "共识节点",
        1: "同步节点",
    };

    return (
        <>
            <Modal visible={visible} caption="新增节点" onClose={close}>
                <Modal.Body>
                    <Form>
                        <Controller
                            control={control}
                            rules={{
                                required: '请选择组织',
                            }}
                            name="OrgId"
                            render={({field, fieldState}) => (
                                <Form.Item
                                    status={formUtils.getStatus({
                                        fieldState,
                                        isValidating,
                                        isSubmitted,
                                    })}
                                    required
                                    label="选择合约"
                                    message={fieldState.error?.message}
                                >
                                    <Select
                                        options={orgList.map((item: any) => ({
                                            text: item.OrgName,
                                            value: String(item.OrgId),
                                        }))}
                                        {...field}
                                        size={'full'}
                                    />
                                </Form.Item>
                            )}
                        />
                        <Controller
                            control={control}
                            rules={{
                                required: '请选择节点',
                            }}
                            name="NodeId"
                            render={({field, fieldState}) => (
                                <Form.Item
                                    status={formUtils.getStatus({
                                        fieldState,
                                        isValidating,
                                        isSubmitted,
                                    })}
                                    required
                                    label="选择节点"
                                    message={fieldState.error?.message}
                                >
                                    <Select
                                        groups={groups}
                                        options={nodeList.map((item: any) => ({
                                            groupKey:String(item.Type),
                                            text: item.NodeName,
                                            value: String(item.NodeId),
                                        }))}
                                        {...field}
                                        size={'full'}
                                        onChange={(v,{option})=>{
                                            if(v){
                                                const NodeId=option?.value||''
                                                const NodeType=option?.groupKey||''
                                                setValue('NodeId', NodeId);
                                                setValue('NodeType', NodeType);
                                            }
                                        }}
                                    />
                                </Form.Item>
                            )}
                        />
                        <Controller
                            control={control}
                            rules={{
                                validate: (input) => {
                                    return Validator.validateIP(input);
                                },
                            }}
                            name="Host"
                            render={({field, fieldState}) =>
                                <Form.Item
                                    status={formUtils.getStatus({
                                        fieldState,
                                        isValidating,
                                        isSubmitted,
                                    })}
                                    required
                                    label="IP地址"
                                    message={fieldState.error?.message}
                                >
                                    <Input placeholder={'IP地址'} {...field} size={'full'}/>
                                </Form.Item>
                            }
                        />
                        <Controller
                            control={control}
                            rules={{
                                validate: (input: string) => {
                                    if (input && getValues('P2pPort') === input) {
                                        return 'RPC端口与P2P端口不可以相同';
                                    }
                                    return Validator.validatePort(input);
                                },
                            }}
                            name="RpcPort"
                            render={({field, fieldState}) =>
                                <Form.Item
                                    status={formUtils.getStatus({
                                        fieldState,
                                        isValidating,
                                        isSubmitted,
                                    })}
                                    required
                                    label="RPC端口"
                                    message={fieldState.error?.message}
                                >
                                    <Input placeholder={'RPC端口'} {...field} size={'full'}/>
                                </Form.Item>
                            }
                        />
                        <Controller
                            control={control}
                            rules={{
                                validate: (input: string) => {
                                    if (input && getValues('RpcPort') === input) {
                                        return 'RPC端口与P2P端口不可以相同';
                                    }
                                    return Validator.validatePort(input);
                                },
                            }}
                            name="P2pPort"
                            render={({field, fieldState}) =>
                                <Form.Item
                                    status={formUtils.getStatus({
                                        fieldState,
                                        isValidating,
                                        isSubmitted,
                                    })}
                                    required
                                    label="P2P端口"
                                    message={fieldState.error?.message}
                                >
                                    <Input placeholder={'P2P端口'} {...field} size={'full'}/>
                                </Form.Item>
                            }
                        />
                        <Controller
                            control={control}
                            name="Reason"
                            rules={{
                                validate: Validator.validateReason
                            }}
                            render={({field, fieldState}) => (
                                <Form.Item
                                    status={formUtils.getStatus({
                                        fieldState,
                                        isValidating,
                                        isSubmitted,
                                    })}
                                    label={'新增理由'}
                                    message={fieldState.error?.message}
                                >
                                    <TextArea
                                        size="full"
                                        showCount
                                        placeholder={'新增共识节点需要其他组织同意，请输入新增理由；新增同步节点无需其他组织同意，可直接添加'}
                                        {...field}
                                    />
                                </Form.Item>
                            )}
                        />
                    </Form>
                </Modal.Body>
                <Modal.Footer>
                    <Button
                        type="primary"
                        onClick={handleSubmit}
                        disabled={!isValid}
                    >
                        确定
                    </Button>
                    <Button type="weak" onClick={onClose}>
                        取消
                    </Button>
                </Modal.Footer>
            </Modal>
        </>
    );
}